package org.footballmanager.pandafootball.system.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.annotation.SystemServiceLog;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.system.dao.FootClubDao;
import org.footballmanager.pandafootball.system.domain.*;
import org.footballmanager.pandafootball.system.form.impl.FootClubSearchForm;
import org.footballmanager.pandafootball.system.mapper.FootClubMapper;
import org.footballmanager.pandafootball.system.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class FootClubServiceImpl extends RepeatServiceImpl<FootClub> implements FootClubService {
    @Autowired
    private FootClubDao footClubDao;
    @Autowired
    private FootClubMapper footClubMapper;
    @Autowired
    private FootSjService footSjService;
    @Autowired
    private FootRankService footRankService;
    @Autowired
    private FootTeamService footTeamService;
    @Autowired
    private FootUserPersonService footUserPersonService;
    @Autowired
    private FootTtService footTtService;
    @Autowired
    private FootQdService footQdService;
    @Autowired
    private FootUserService footUserService;

    /**
     * 更新所有俱乐部信息
     *
     * @param entity  参数
     * @param request 参数
     * @return 返回值
     */
    @Override
    @Transactional
    @SystemServiceLog(description = "更新所有俱乐部信息")
    public int updateAll(FootClub entity, HttpServletRequest request) {
        FootUser user = footUserService.get(entity.getUserId());
        FootQd qd = footQdService.get(entity.getQdId());
        if (qd != null) {
            entity.setQdId(qd.getId());
            footRankService.updateRankQdName(user.getId(), qd, request);
            footTtService.updateTtQdName(user.getId(), qd, request);
            //初始资金分配
            footTeamService.createZjTeamByUserId(entity.getUserId(), qd.getId(), qd.getQdmc(), request);
            //随机分配11个球员
            footUserPersonService.randomLow75(user.getId(), request);
        }
        return super.updateNotNull(entity, request);
    }

    /**
     * 根据赛季获取积分榜
     *
     * @param isGe24 是否获取场次大于24的
     * @param sjId   赛季主键
     * @return 常规赛积分榜
     */
    @Override
    @SystemServiceLog(description = "根据赛季获取积分榜")
    public List<FootClub> getScoreboard(boolean isGe24, Long sjId) {
        FootClubSearchForm footClubSearchForm = new FootClubSearchForm();
        footClubSearchForm.setSj(sjId);
        if (isGe24) {
            footClubSearchForm.setBscc(24);
        }
        return findall(footClubSearchForm);
    }

    /**
     * 根据用户主键获取记录
     *
     * @param userId 用户主键
     * @return 记录
     */
    @Override
    @SystemServiceLog(description = "根据用户主键获取Club记录")
    public FootClub findByUserid(Long userId) {
        return footClubMapper.findByUserIdAndSjId(userId, footSjService.getSj());
    }

    /**
     * 重新计算排名
     *
     * @param request 请求
     */
    @Override
    @Transactional
    @SystemServiceLog(description = "重新计算排名")
    public void reComputeRanking(HttpServletRequest request) {
        List<FootClub> list = this.getScoreboard(false, footSjService.getSj());
        if (null != list && !list.isEmpty()) {
            int i = 1;
            for (FootClub fc : list) {
                fc.setPm(i++);
                if (request != null) {
                    fc.setUpdateId((Long) request.getSession().getAttribute(Constants.USERID));
                } else {
                    fc.setUpdateId(1L);
                }
                fc.setUpdateTime(new Date());
                footClubDao.updateByPrimaryKeySelective(fc);
            }
        }
    }

    /**
     * 添加新赛季的俱乐部信息到表中
     *
     * @param sjId    赛季主键
     * @param request 请求
     */
    @Override
    @SystemServiceLog(description = "添加新赛季的俱乐部信息到表中")
    public void addNewClubInfo(Long sjId, HttpServletRequest request) {
        //获取所有用户，根据用户是否参加常规赛重新添加club信息到数据库中
        Example example = new Example(FootClub.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getLastSj());
        criteria.andEqualTo("delFlag", 0);
        List<FootClub> list = this.findall(example);
        if (list != null && !list.isEmpty()) {
            for (FootClub club : list) {
                FootClub newclub = new FootClub();
                BeanUtils.copyProperties(club, newclub);
                newclub.setSj(sjId);
                newclub.setId(null);
                //判断是否有重复数据
                if (!this.findRepeatData(newclub)) {
                    this.save(newclub, request);
                }

                FootTeam team = footTeamService.getTeamByUserid(newclub.getUserId());

                FootRank newrank = new FootRank();
                newrank.setSj(sjId);
                newrank.setUserId(newclub.getUserId());
                newrank.setQdId(team.getQdId());
                //判断是否有重复数据
                if (!footRankService.findRepeatData(newrank)) {
                    footRankService.save(newrank, request);
                }

                FootTt newTt = new FootTt();
                newTt.setSj(sjId);
                newTt.setUserId(newclub.getUserId());
                newTt.setQdId(team.getQdId());
                //判断是否有重复数据
                if (!footTtService.findRepeatData(newTt)) {
                    footTtService.save(newTt, request);
                }
            }
        }
    }

    /**
     * 处理重复的代码
     *
     * @param newclub 俱乐部实体类
     * @return 是否有值
     */
    private boolean findRepeatData(FootClub newclub) {
        Example example = new Example(FootClub.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("qdId", newclub.getQdId());
        criteria.andEqualTo(Constants.USERID, newclub.getUserId());
        criteria.andEqualTo("sj", newclub.getSj());
        criteria.andEqualTo("delFlag", 0);
        List<FootClub> list = this.findall(example);
        return null != list && !list.isEmpty();
    }

    /**
     * 根据赛季找所有俱乐部其他奖励的对应信息
     *
     * @param type 类型
     * @param sjId 赛季主键
     * @return 所有俱乐部其他奖励的对应信息
     */
    @Override
    @SystemServiceLog(description = "根据赛季找所有俱乐部其他奖励的对应信息")
    public List<FootClub> getWinClubsBySj(int type, Long sjId) {
        Example example = new Example(FootClub.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andGreaterThanOrEqualTo("bscc", 24);
        criteria.andEqualTo("delFlag", 0);
        criteria.andEqualTo("sj", sjId);
        if (type == 1) {
            example.orderBy("sq").desc();
        } else if (type == 2) {
            example.orderBy("jq").desc();
        } else if (type == 3) {
            criteria.andGreaterThanOrEqualTo("bscc", 30);
        } else if (type == 4) {
            criteria.andGreaterThanOrEqualTo("sl", 0.2D);
        } else if (type == 5) {
            criteria.andGreaterThanOrEqualTo("sl", 0.5D);
        } else if (type == 6) {
            criteria.andGreaterThanOrEqualTo("sl", 0.8D);
        } else if (type == 7) {
            criteria.andGreaterThanOrEqualTo("jq", 50);
        } else if (type == 8) {
            criteria.andGreaterThanOrEqualTo("jq", 100);
        }
        return this.findall(example);
    }

    /**
     * 获取当赛季的前i名信息
     *
     * @param i 第i名
     * @return 俱乐部信息
     */
    @Override
    @SystemServiceLog(description = "获取当赛季的前i名信息")
    public FootClub getTopClubBySj(int i) {
        int position = i - 1;
        List<FootClub> list = this.getScoreboard(true, footSjService.getSj());
        if (null != list && (list.size() > position)) {
            return list.get(position);
        }
        return null;
    }

    /**
     * 保存新的俱乐部信息到数据库
     *
     * @param user    用户
     * @param request 请求
     * @return 主键
     */
    @Override
    @SystemServiceLog(description = "保存新的俱乐部信息到数据库")
    public Serializable saveNewClub(FootUser user, HttpServletRequest request) {
        FootClub fc = new FootClub();
        fc.setQdId(user.getQdId());
        fc.setUserId(user.getId());
        fc.setSj(footSjService.getSj());
        return this.save(fc, request);
    }

    /**
     * 根据用户主键查找所有对应的俱乐部信息
     *
     * @param userId 用户主键
     * @param sjId   赛季主键
     * @return 所有对应的俱乐部信息
     */
    @Override
    @SystemServiceLog(description = "根据用户主键查找所有对应的俱乐部信息")
    public List<FootClub> getClubsByUseridandSj(Long userId, Long sjId) {
        Example example = new Example(FootClub.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", sjId);
        criteria.andEqualTo(Constants.USERID, userId);
        criteria.andEqualTo("delFlag", 0);
        return this.findall(example);
    }

    /**
     * 根据赛季和用户主键来获取当前用户的名次
     *
     * @param userId 用户主键
     * @return 参加季后赛类型
     */
    @Override
    @SystemServiceLog(description = "根据赛季和用户主键来获取当前用户的名次")
    public Boolean findNumByUserId(Long userId) {
        List<FootClub> list = this.getScoreboard(false, footSjService.getSj());
        if (list != null && !list.isEmpty()) {
            int j = 0;
            for (int i = 0; i < list.size(); i++) {
                FootClub club = list.get(i);
                if (club.getUserId().equals(userId)) {
                    j = i;
                }
            }
            return j < 16;
        }
        return false;
    }

    /**
     * 获取top名俱乐部信息
     *
     * @param sjId   赛季主键
     * @param top    第Top名
     * @param buttom 最后
     * @return 俱乐部信息列表
     */
    @Override
    @SystemServiceLog(description = "获取top名俱乐部信息")
    public List<FootClub> findTopClub(Long sjId, Integer top, Integer buttom) {
        Example example = new Example(FootClub.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", sjId);
        criteria.andGreaterThanOrEqualTo("pm", top);
        criteria.andLessThanOrEqualTo("pm", buttom);
        criteria.andEqualTo("delFlag", 0);
        example.orderBy("pm").asc();
        return this.findall(example);
    }

    /**
     * 根据条件查询俱乐部信息列表
     *
     * @param footClubSearchForm 条件
     * @return 列表
     */
    @Override
    @SystemServiceLog(description = "根据条件查询俱乐部信息列表")
    public List<FootClub> findall(FootClubSearchForm footClubSearchForm) {
        return footClubMapper.findall(footClubSearchForm);
    }

    /**
     * 根据俱乐部主键查询俱乐部信息
     *
     * @param id 主键
     * @return 记录
     */
    @Override
    @SystemServiceLog(description = "根据俱乐部主键查询俱乐部信息")
    public FootClub get(Serializable id) {
        return footClubMapper.findById(id);
    }

    /**
     * 根据条件查询俱乐部信息列表
     *
     * @param entityname         实体类名
     * @param map                参数
     * @param footClubSearchForm 条件
     */
    @Override
    @SystemServiceLog(description = "根据条件查询俱乐部信息列表")
    public void search(String entityname, Model map, FootClubSearchForm footClubSearchForm) {
        map.addAttribute(String.format(Constants.FORMNAME, entityname), footClubSearchForm);
        List<FootClub> list = this.findall(footClubSearchForm);
        map.addAttribute(String.format(Constants.LISTENTITY, entityname), list);
    }

    /**
     * 更改球队设置
     *
     * @param footClub 俱乐部实体类
     * @param request  请求
     */
    @Override
    @SystemServiceLog(description = "更改球队设置")
    public void changeQd(FootClub footClub, HttpServletRequest request) {
        FootClub fc = footClubDao.selectByPrimaryKey(footClub.getId());
        //换队壳
        FootUser user = footUserService.get(fc.getUserId());
        FootTeam team = footTeamService.getTeamByUserid(user.getId());
        FootRank rank = footRankService.findByUserid(user.getId());
        FootQd newqd = footQdService.get(footClub.getQdId());
        if (team != null) {
            team.setId(newqd.getId());
            rank.setQdId(newqd.getId());
            footRankService.updateNotNull(rank, request);
            footTeamService.updateAll(team, request);
        }
    }

    /**
     * 补全本赛季没有加入的玩家
     *
     * @param sjId 赛季主键
     */
    @Override
    @SystemServiceLog(description = "补全本赛季没有加入的玩家")
    public void processFixBySj(Long sjId) {
        List<FootUser> list = footUserService.getAllWithoutAdmin(null);
        if (list == null || list.isEmpty()) {
            return;
        }
        for (FootUser footUser : list) {
            FootClub club = findByUserIdAndSj(footUser.getId(), sjId);
            if (club == null && footUser.getJoins()) {
                FootClub oldClub = findByUserIdAndSj(footUser.getId(), footSjService.getLastSj());
                if (oldClub != null) {
                    FootClub newClub = new FootClub();
                    BeanUtils.copyProperties(oldClub, newClub);
                    newClub.setId(null);
                    newClub.setSj(sjId);
                    this.save(newClub, null);
                } else {
                    this.saveNewClub(footUser, null);
                }
            }
        }
    }

    /**
     * 根据用户主键和赛季主键查找记录
     *
     * @param userId 用户主键
     * @param sjId   赛季主键
     * @return 俱乐部记录
     */
    private FootClub findByUserIdAndSj(Long userId, Long sjId) {
        Example example = new Example(FootClub.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("sj", sjId);
        criteria.andEqualTo("delFlag", 0);
        return this.findByExample(example);
    }

    /**
     * 根据用户主键删除对应信息
     *
     * @param userId  用户主键
     * @param request 请求
     */
    @Override
    @SystemServiceLog(description = "根据用户主键删除对应俱乐部信息")
    public void deleteByUserId(Long userId, HttpServletRequest request) {
        //删除俱乐部
        List<FootClub> clubList = this.getClubsByUseridandSj(userId, footSjService.getSj());
        if (clubList != null && !clubList.isEmpty()) {
            for (FootClub fc : clubList) {
                this.delete(fc.getId(), request);
            }
        }
    }
}
